using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using LiveStock.Recommendation;

namespace LiveStock.Recommendation
{
  class CompanySearch
  {
    string searchString;
    int resultsCount;
    public List<Stock> companies;


    public CompanySearch()
    {
      resultsCount = -1;
    }


    public string SearchString
    {
      get { return searchString; }
      set { searchString = value; }
    }


    public void Lookup(string searchStr)
    {
      searchString = searchStr;

      if (searchString != null)
      {
        string searchUrl = "http://finance.yahoo.com/lookup?s=" + (searchString) + "&t=S&m=US";
        StringBuilder sb = new StringBuilder();
        byte[] buf = new byte[8192];

        try
        {
          HttpWebRequest request = (HttpWebRequest)WebRequest.Create(searchUrl);
          HttpWebResponse response = (HttpWebResponse)request.GetResponse();
          Stream resStream = response.GetResponseStream();

          string tempString = null;
          int count = 0;

          do
          {
            count = resStream.Read(buf, 0, buf.Length);

            if (count != 0)
            {
              tempString = Encoding.ASCII.GetString(buf, 0, count);
              sb.Append(tempString);
            }
          }
          while (count > 0);
        }
        catch (Exception e)
        {
          Console.WriteLine(e.Message);
        }

        if (sb.Length > 0)
        {
          this.AnalyzeWebPage(sb.ToString());
        }
      }
      else
      {
        Console.WriteLine("Invalid Search String: " + searchStr);
      }
    }


    private void AnalyzeWebPage(string str)
    {
      resultsCount = GetResultsCount(str);

      if (resultsCount > 0)
      {
        companies = GetCompanies(str);
        foreach (Stock stock in companies)
        {
          Console.WriteLine(stock.CompanyName + " [" + stock.StockSymbol + "]");
        }
      }
    }


    private int GetResultsCount(string str)
    {
      int numberOfResults = -1;

      if (str != null)
      {
        if (Regex.IsMatch(str, "Your search for '.*' returned no Stock matches."))
        {
          numberOfResults = 0;
        }
        else
        {
          Regex regex = new Regex(@"Showing (\d+) - (\d+) of (\d+)");
          Match match = regex.Match(str);
          GroupCollection gc = match.Groups;

          if(match.Success)
          {
            numberOfResults = int.Parse(gc[3].Value);
          }
        }
      }

      return numberOfResults;
    }


    private List<Stock> GetCompanies(string str)
    {
      List<Stock> list = new List<Stock>();

      if (str != null)
      {
        for (Match match = Regex.Match(str, @"<td><a href=""/q\?s=[^""]*"">([^<]+)</a></td><td>([^<]+)</td><td>([^<]+)</td><td>([^<]+)</td>"); match.Success; match = match.NextMatch())
        {
          GroupCollection gc = match.Groups;
          Stock stock = new Stock();
          stock.StockSymbol = gc[1].Value;
          stock.CompanyName = gc[2].Value;
          stock.Exchange = gc[3].Value;
          stock.Industry = gc[4].Value;
          list.Add(stock);
        }
      }

      if (list.Count == 0)
      {
        list = null;
      }

      return list;
    }

  }
}
